//进程创建
 //进程初始化
 const Process = {
 processInitial : function(processNum){
    let objArr_process = [];
    for(let index = 0;index < processNum;index++){
        objArr_process.push({
            proId : '',//进程Id
            arrivalTime : 0,//进程到达时间
            serivceTime : 0,//进程服务时间
            startTime : 0,//进程开始时间
            finishTime : 0,//进程结束时间
            wholeTime : 0,//进程周转时间
            rtTime: 0,//带权周转时间
        });//创建空的对象（对象模拟进程）
    }
    return objArr_process;
},
 //进程赋值
 //objArr_pro为只有到达时间和服务时间的原数据，类似[{arrivalTime:1,serivceTime:2},{arrivalTime:2,serivceTime:2}]
process : function(objArr_process,objArr_pro){
    for(let key in objArr_pro){
        objArr_process[key].proId = key;
        objArr_process[key].arrivalTime = objArr_pro[key].arrivalTime;
        objArr_process[key].serivceTime = objArr_pro[key].serivceTime; 
    }
    return objArr_process;
},

// console.log(a);


//FCFS算法
 fcfs : function(objArr_process){
    //按到达时间进行排序，既进程优先级
    objArr_process =  this.fcfssort(objArr_process);
    let sumwholeTime = 0;
    let sumrtTime = 0;
    for(let key = 0;key < objArr_process.length;key++){
        if(key !==0){
            objArr_process[key].startTime = objArr_process[key-1].finishTime;
        }else{
            objArr_process[key].startTime = objArr_process[key].arrivalTime;//进程开始时间计算
        }
        objArr_process[key].finishTime = objArr_process[key].startTime + objArr_process[key].serivceTime;//结束时间计算
        objArr_process[key].wholeTime = objArr_process[key].finishTime - objArr_process[key].arrivalTime;//周转时间计算
        objArr_process[key].rtTime = objArr_process[key].wholeTime / objArr_process[key].serivceTime;//带权周转时间计算

        sumwholeTime += objArr_process[key].wholeTime;
        sumrtTime+= objArr_process[key].rtTime;
    }
    let processnum = objArr_process.length;
    objArr_process.push(sumwholeTime/processnum);
    objArr_process.push(sumrtTime/processnum);
    return objArr_process;
},
 //FCFS排序
 fcfssort : function(objArr_process){
    let temp = {};
    for(let j = 0 ;j<objArr_process.length;j++){
        for(let index = j+1;index <  objArr_process.length;index++){
            if(objArr_process[j].arrivalTime > objArr_process[index].arrivalTime){
                temp = objArr_process[index];
                objArr_process[index] = objArr_process[j];
                objArr_process[j] = temp;
            }
        }
    }
    return objArr_process;
},

//SJF算法

 sjf : function(objArr_process){
    //  console.log(objArr_process);
    //  console.log("---------------");
    objArr_process =  this.fcfssort(objArr_process);//暂时先按到达时间排序
    let processnum = objArr_process.length;//进程数
    //第一个到达的还是会第一个运行
    objArr_process[0].startTime = objArr_process[0].arrivalTime;
    objArr_process[0].finishTime = objArr_process[0].startTime +objArr_process[0].serivceTime;
    
    let finished_process = [objArr_process[0]];//已经完成进程
    objArr_process.shift();//把第一个删掉
    let wait_process = [];//等待中的进程
    let unarrival_process = [];//未到达进程

    for(let key in objArr_process){
        key = parseInt(key);
        if(objArr_process[key].arrivalTime <= finished_process[finished_process.length-1].finishTime){
            wait_process.push(objArr_process[key]);
        }else{
            unarrival_process.push(objArr_process[key]);
        } 
        
    }

    //核心部分
    while(wait_process.length != 0){
        let key = 0;
        wait_process  = this.sjfsort(wait_process);
        
        wait_process[key].startTime = finished_process[finished_process.length-1].finishTime;
        wait_process[key].finishTime = wait_process[key].startTime + wait_process[key].serivceTime;

        finished_process.push(wait_process[key]);
        wait_process.shift();
 
        
        let length = unarrival_process.length;
        while(length !== 0){
            if(unarrival_process[0].arrivalTime < finished_process[finished_process.length-1].finishTime){
                wait_process.push(unarrival_process[0]);

                unarrival_process.shift();
            }
            length--;
        }

    }


    let sumwholeTime = 0;
    let sumrtTime = 0;
    for(let value of finished_process){
        value.wholeTime = value.finishTime - value.arrivalTime;
        value.rtTime = value.wholeTime / value.serivceTime;

        sumwholeTime +=value.wholeTime;
        sumrtTime += value.rtTime;
    }


    objArr_process = finished_process;
    objArr_process.push(sumwholeTime / processnum);
    objArr_process.push(sumrtTime / processnum);

 

  
    return objArr_process;
},
 sjfsort : function(wait_process){
    let temp = {};
    for(let index = 0;index <  wait_process.length;index++){
        for(let j = index + 1;j < wait_process.length;j++){
            if(wait_process[index].serivceTime > wait_process[j].serivceTime){
            temp = wait_process[j];
            wait_process[j] = wait_process[index];
            wait_process[index] = temp;
            }
        }
    }
    return wait_process;
},

//可抢占的最短作业优先
 srt : function(objArr_process3){
    objArr_process3 =  this.fcfssort(objArr_process3);//暂时先按到达时间排序
    //第一个到达的还是会第一个运行
    objArr_process3[0].startTime = objArr_process3[0].arrivalTime;
    // objArr_process[0].finishTime = objArr_process[0].startTime +objArr_process[0].serivceTime;
    
    let finished_process = [];//已经完成进程
    let on_process = objArr_process3[0];//正在进行的进程
    let wait_process = [];//等待中的进程
    let unarrival_process = [];//未到达进程

    on_process.remainTime = on_process.serivceTime;//剩余时间
    on_process.finishTime = on_process.startTime + on_process.serivceTime;//预计结束时间
    objArr_process3.shift();

    for(let key in objArr_process3){
        key = parseInt(key);
        if(objArr_process3[key].arrivalTime <= on_process.finishTime){
            on_process.remainTime = on_process.finishTime - objArr_process3[key].arrivalTime;//剩余时间
            if(objArr_process3[key].serivceTime < on_process.remainTime){
                wait_process.push(on_process);
                on_process = objArr_process3[key];//进程改变
                on_process.remainTime = on_process.serivceTime;
                on_process.startTime = on_process.arrivalTime;
                on_process.finishTime = on_process.startTime + on_process.remainTime;
            }else{
                objArr_process3[key].remainTime = objArr_process3[key].serivceTime;
                wait_process.push(objArr_process3[key]);
            }
        }else{
            objArr_process3[key].remainTime = objArr_process3[key].serivceTime
            unarrival_process.push(objArr_process3[key]);
        }
    }
    finished_process.push(on_process);
    on_process = null;
    let length = unarrival_process.length;
    
    while(length > 0){
        
        if(on_process == null){
            on_process = wait_process[0];
            on_process.startTime = finished_process[finished_process.length-1].finishTime;
            on_process.finishTime = on_process.startTime + on_process.remainTime;
            wait_process.shift();
        }
        // console.log(wait_process);
        if(unarrival_process[0].arrivalTime <= on_process.finishTime){
            on_process.remainTime = on_process.finishTime - unarrival_process[0].arrivalTime;
            if(unarrival_process[0].remainTime < on_process.remainTime){
                wait_process.push(on_process);
                on_process = unarrival_process[0];//进程改变
                on_process.remainTime = on_process.serivceTime;
                on_process.startTime = on_process.arrivalTime;
                on_process.finishTime = on_process.startTime + on_process.remainTime;
            }else{
                console.log("--");
                // console.log(unarrival_process[0]);
                wait_process.push(unarrival_process[0]);
                // wait_process = this.srtsort(wait_process);
            }
        }else{
            finished_process.push(on_process);
            on_process = null;
        }
        unarrival_process.shift();
        length--;
        
    }
    // console.log(unarrival_process);
    wait_process = this.srtsort(wait_process);
    // console.log(wait_process);
    finished_process.push(on_process);
    while(wait_process.length !== 0){
        
        if(wait_process[0].serivceTime == wait_process[0].remainTime){
            wait_process[0].startTime = finished_process[finished_process.length-1].finishTime;
        }
       
        wait_process[0].finishTime = finished_process[finished_process.length-1].finishTime + wait_process[0].remainTime;
        finished_process.push(wait_process[0]);
        wait_process.shift();
    }
//    console.log(finished_process);
    return this.coputer_whole(finished_process);
 },
 srtsort : function(wait_process){
    let temp = {};
    for(let index = 0;index <  wait_process.length;index++){
        for(let j = index + 1;j < wait_process.length;j++){
            if(wait_process[index].remainTime > wait_process[j].remainTime){
            temp = wait_process[j];
            wait_process[j] = wait_process[index];
            wait_process[index] = temp;
            }
            if(wait_process[index].remainTime == wait_process[j].remainTime && wait_process[index].arrivalTime > wait_process[j].arrivalTime){
                temp = wait_process[j];
                wait_process[j] = wait_process[index];
                wait_process[index] = temp;
            }
        }
    }
    return wait_process;
},

 coputer_whole : function(finished_process){
    
    let sumwholeTime = 0;
    let sumrtTime = 0;
    // console.log(finished_process.length);
    for(let value of finished_process){
        value.wholeTime = value.finishTime - value.arrivalTime;
        value.rtTime = value.wholeTime / value.serivceTime;

        sumwholeTime +=value.wholeTime;
        sumrtTime += value.rtTime;
    }
    let objArr_process = finished_process;
    let processnum = finished_process.length;
    objArr_process.push(sumwholeTime / processnum);
    objArr_process.push(sumrtTime / processnum);

    return objArr_process;
},
//HRRN
 hrrn : function(objArr_process4){
    // console.log(objArr_process4);
    objArr_process4 =  this.fcfssort(objArr_process4);//暂时先按到达时间排序
    let process = objArr_process4;//备份
    let processnum = objArr_process4.length;//进程数
    //第一个到达的还是会第一个运行
    objArr_process4[0].startTime = objArr_process4[0].arrivalTime;
    objArr_process4[0].finishTime = objArr_process4[0].startTime +objArr_process4[0].serivceTime;
    
    let finished_process = [];//已经完成进程
    let wait_process = [];//等待中的进程
    let unarrival_process = [];//未到达进程

    finished_process.push(objArr_process4[0]);
    objArr_process4.shift();
    for(let key in objArr_process4){
        key = parseInt(key);
        if(objArr_process4[key].arrivalTime !== 0 ){
            if(objArr_process4[key].arrivalTime <= finished_process[finished_process.length-1].finishTime){
                objArr_process4[key].R = 1 + (finished_process[finished_process.length-1].finishTime - objArr_process4[key].arrivalTime)/objArr_process4[key].serivceTime;
                wait_process.push(objArr_process4[key]);
            }else{
                unarrival_process.push(objArr_process4[key]);
            } 
        }
    }


    while(wait_process.length != 0){
        let key = 0;
        wait_process  = this.hrrnsort(wait_process);

        wait_process[key].startTime = finished_process[finished_process.length-1].finishTime;
        wait_process[key].finishTime = wait_process[key].startTime + wait_process[key].serivceTime;

        finished_process.push(wait_process[key]);
        
        
        
        wait_process.shift();
       
        let length = unarrival_process.length;
        while(length !== 0){
            if(unarrival_process[0].arrivalTime < finished_process[finished_process.length-1].finishTime){
                unarrival_process[0].R = 1 +(finished_process[finished_process.length-1].finishTime - unarrival_process[0].arrivalTime)/unarrival_process[0].serivceTime;
                wait_process.push(unarrival_process[0]);
                unarrival_process.shift();
            }
            length--;
        }
        for(let value of wait_process){
            value.R = 1 +(finished_process[finished_process.length-1].finishTime - value.arrivalTime)/value.serivceTime;
        }
       
    }

    let sumwholeTime = 0;
    let sumrtTime = 0;
    
    for(let value of finished_process){
        value.wholeTime = value.finishTime - value.arrivalTime;
        value.rtTime = value.wholeTime / value.serivceTime;

        sumwholeTime +=value.wholeTime;
        sumrtTime += value.rtTime;
    }
    finished_process.push(sumwholeTime / processnum);
    finished_process.push(sumrtTime / processnum);

    
    return finished_process;
},

 hrrnsort : function(wait_process){
    let temp = {};
    for(let index = 0;index <  wait_process.length;index++){
        for(let j = index + 1;j < wait_process.length;j++){
            if(wait_process[index].R < wait_process[j].R){
            temp = wait_process[j];
            wait_process[j] = wait_process[index];
            wait_process[index] = temp;
            }
        }
    }
    return wait_process;
}

}

window.onload = function(){
    $(document).ready(function(){
        let processnum = 0;
        let objArr_pro = [];
        $(".button").click(function(){
            processnum = onclick_btn();
        });
        
        $("#suanfa input").click(function(){
            $("#FCFS").html("<div></div>");
            $("#SRT").html("<div></div>");
            $("#SJF").html("<div></div>");
            $("#HRRN").html("<div></div>");

            objArr_pro = onclick_show();

            let allprocess = Process.process(Process.processInitial(processnum),objArr_pro);
            let fcfs_process = output(Process.fcfs(allprocess)); 
            $("#FCFS").html(fcfs_process);

             allprocess = Process.process(Process.processInitial(processnum),objArr_pro);
            let sjf_process = Process.sjf(allprocess); 
            console.log("SJF");
            console.log(sjf_process);
            $("#SJF").html(output(sjf_process));
            
            allprocess = Process.process(Process.processInitial(processnum),objArr_pro);
            let srt_process = Process.srt(allprocess);
            console.log("SRT");
            console.log(srt_process); 
            $("#SRT").html(output(srt_process));

            allprocess = Process.process(Process.processInitial(processnum),objArr_pro);
            let hrrn_process = Process.hrrn(allprocess); 
            console.log("HRRN");
            console.log(hrrn_process);
            $("#HRRN").html(output(hrrn_process));
        });
        function onclick_btn(){
            let processnum = parseInt($(".input").val());
            let process_in = ``;
            for(let index = 1 ;index <= processnum ;index++){
                process_in += `<div class="process_in">
            <p style="color:red">进程${index}</p>
            <p>到达时间：</p>
            <input type="text">
            <p>服务时间：</p>
            <input type="text">
        </div>`
            }
            $("#arr").html(process_in);
            return processnum;
        }
        function onclick_show(){
            let all_input = $("#arr input");
            let objArr_pro = [];
            for(let index = 0 ;index < processnum*2 ;index +=2){
                objArr_pro.push({
                    arrivalTime: parseInt(all_input[index].value),
                    serivceTime: parseInt(all_input[index+1].value)
                });
            }
            return objArr_pro;
        }
        function output(suanfa_process){
            let table_process = '';
            for(let index = 0;index <suanfa_process.length;index++){
                if(index === processnum){
                     table_process += `   <tr>
                    <th>平均周转时间时间</th>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>${suanfa_process[index].toFixed(2) || 0}</td>
                    <td></td>
                </tr>`
                }else if(index === processnum+1){
                     table_process += `   <tr>
                    <th>平均带权周转时间</th>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>${suanfa_process[index].toFixed(2) || 0}</td>
                </tr>`
                }else{
                 table_process += ` <tr>
                    <td>${suanfa_process[index].proId}</td>
                    <td>${suanfa_process[index].arrivalTime}</td>
                    <td>${suanfa_process[index].serivceTime}</td>
                    <td>${suanfa_process[index].startTime}</td>
                    <td>${suanfa_process[index].finishTime}</td>
                    <td>${suanfa_process[index].wholeTime}</td>
                    <td>${suanfa_process[index].rtTime.toFixed(2) || 0}</td>
                </tr>`
                }
            }
            let suanfa = `<table>
            <tr>
                <th>进程ID</th>
                <th>到达时间</th>
                <th>服务时间</th>
                <th>开始时间</th>
                <th>结束时间</th>
                <th>周转时间</th>
                <th>带权周转时间</th>
            </tr>
            ${table_process}
        </table>`;
            return suanfa;
        }
    });
}